package GUI;

import java.util.ArrayList;
import java.util.Calendar;

import Control.MilitaryBase;
import Control.UFO;

public class GraphsArea {
	int x,y,width,height;
	public Graph airportDistanceGraph;
	public Graph militaryBaseDistanceGraph;
	public Graph populationDensityGraph;
	public Graph hoursGraph;
	public Graph monthsGraph;
	public Graph weatherStationsGraph;
	public Button airport;
	public Button popDensity;
	public Button militaryBases;
	public Button weatherStations;
	public Button hours;
	public Button months;


	public final int AIRPORT = 0;
	public final int POPDENSITY = 1;
	public final int MILITARYBASES = 2;
	public final int HOURS = 3;
	public final int MONTHS = 4;
	public final int WEATHERSTATIONS = 5;

	int activeGraph=AIRPORT;

	int airportMaxYVal = 50;
	int popDensityMaxYVal = 20;
	int MilitaryBasesMaxYVal = 20;
	int hoursMaxYVal = 20;
	int monthsMaxYVal = 20;
	int weatherStationsMaxYVal =20;

	public String s1= "number of";
	public String s2= "sightings";


	public GraphsArea(){
		this.x=0;
		this.y=90;
		this.width = GV.width;
		this.height = GV.height-148;
		airportDistanceGraph = new Graph(110,160,800,420,airportMaxYVal,
				"distance from","closest airport (in Km)",s1,s2,0,17);
		airportDistanceGraph.xLabels = createAirportXLabels();
		militaryBaseDistanceGraph = new Graph(110,160,800,420,MilitaryBasesMaxYVal,
				"distance from","closest military base (in Km)",s1,s2,0,17);
		militaryBaseDistanceGraph.xLabels = createAirportXLabels();
		populationDensityGraph = new Graph(110,160,800,420,popDensityMaxYVal,
				"popluation density ((number of abitants / km2) / 1000 )","",s1,s2,0,17);
		populationDensityGraph.xLabels = createPopDensityXLabels();
		hoursGraph = new Graph(110,160,800,420,hoursMaxYVal,
				"hours","",s1,s2,0,23);
		hoursGraph.xLabels = createHoursXLabels();
		monthsGraph = new Graph(110,160,800,420,monthsMaxYVal,
				"months","",s1,s2,0,11);
		monthsGraph.xLabels = createMonthsXLabels();
		weatherStationsGraph = new Graph(110,160,800,420,weatherStationsMaxYVal,
				"distance from closest","weather station (in Km)",s1,s2,0,17);
		weatherStationsGraph.xLabels = createAirportXLabels();
		weatherStations = new Button("Weather Stations",730,100);
		airport = new Button("Airports",50,100);
		popDensity = new Button("Population density",165,100);
		hours = new Button("Hours",355,100);
		months = new Button("Months",465,100);
		militaryBases = new Button("Military Bases",585,100);
		airport.state=true;
	}

	private ArrayList<String> createHoursXLabels() {
		ArrayList<String> list = new ArrayList<String>();

		list.add("0");list.add("1");list.add("2");list.add("3");
		list.add("4");list.add("5");list.add("6");list.add("7");
		list.add("8");list.add("9");list.add("10");list.add("11");
		list.add("12");list.add("13");list.add("14");list.add("15");
		list.add("16");list.add("17");list.add("18");list.add("19");
		list.add("20");list.add("21");list.add("22");list.add("23");
		return list;
	}
	private ArrayList<String> createMonthsXLabels() {
		ArrayList<String> list = new ArrayList<String>();

		list.add("Jan");list.add("Feb");list.add("Mar");list.add("Apr");
		list.add("May");list.add("Jun");list.add("Jul");list.add("Aug");
		list.add("Sep");list.add("Oct");list.add("Nov");list.add("Dec");
		return list;
	}
	private ArrayList<String> createAirportXLabels() {
		ArrayList<String> list = new ArrayList<String>();

		list.add("0<x<10");list.add("10<x<20");list.add("20<x<30");list.add("30<x<40");
		list.add("40<x<50");list.add("50<x<60");list.add("60<x<70");list.add("70<x<80");
		list.add("80<x<90");list.add("90<x<100");list.add("100<x<110");list.add("110<x<120");
		list.add("120<x<130");list.add("130<x<140");list.add("140<x<150");list.add("150<x<160");
		list.add("160<x<170");list.add("x>170");
		return list;
	}
	private ArrayList<String> createPopDensityXLabels() {
		ArrayList<String> list = new ArrayList<String>();

		list.add("0<x<0.5");list.add("0.5<x<1");list.add("1<x<1.5");list.add("1.5<x<2");
		list.add("2<x<2.5");list.add("2.5<x<3");list.add("3<x<3.5");list.add("3.5<x<4");
		list.add("4<x<4.5");list.add("4.5<x<5");list.add("5<x<5.5");list.add("5.5<x<6");
		list.add("6<x<6.5");list.add("6.5<x<7");list.add("7<x<7.5");list.add("7.5<x<8");
		list.add("8<x<8.5");list.add("x>8.5");
		return list;
	}

	private ArrayList<String> createMilitaryXLabels() {
		ArrayList<String> list = new ArrayList<String>();

		list.add("0<x<10");list.add("10<x<20");list.add("20<x<30");list.add("30<x<40");
		list.add("40<x<50");list.add("50<x<60");list.add("60<x<70");list.add("70<x<80");
		list.add("80<x<90");list.add("90<x<100");list.add("100<x<110");list.add("110<x<120");
		list.add("120<x<130");list.add("130<x<140");list.add("140<x<150");list.add("150<x<160");
		list.add("160<x<170");list.add("x>170");
		//list.add("0<D<30");list.add("30<D<60");list.add("60<D<90");list.add("90<D<120");
		//list.add("120<D<150");list.add("150<D<180");list.add("180<D<210");list.add("210<D<240");
		//list.add("240<D<270");list.add("270<D<300");list.add(">300");
		return list;
	}
	private ArrayList<String> createWeatherXLabels() {
		ArrayList<String> list = new ArrayList<String>();

		list.add("0<x<10");list.add("10<x<20");list.add("20<x<30");list.add("30<x<40");
		list.add("40<x<50");list.add("50<x<60");list.add("60<x<70");list.add("70<x<80");
		list.add("80<x<90");list.add("90<x<100");list.add("100<x<110");list.add("110<x<120");
		list.add("120<x<130");list.add("130<x<140");list.add("140<x<150");list.add("150<x<160");
		list.add("160<x<170");list.add("x>170");

		return list;
	}

	public void draw(){
		if(GV.hoursPanel.graphButton.state){
			//draw the graphs
			GV.hoursPanel.clusterButton.state=false;
			drawBackGroud();

			airport.draw();
			popDensity.draw();
			hours.draw();
			months.draw();
			militaryBases.draw();
			weatherStations.draw();
			updateActiveGraph();
			drawGraph();
		}

	}


	private void drawBackGroud() {
		GV.processing.strokeWeight(2);
		GV.processing.rectMode(GV.processing.CORNER);
		GV.processing.fill(GV.backGroundColor);
		GV.processing.stroke(80);
		GV.processing.rect(x,y,width,height);
	}

	public void drawGraph(){
		switch (activeGraph) {
		case AIRPORT:	airportDistanceGraph.draw(); break;
		case POPDENSITY:	populationDensityGraph.draw(); break;
		case MILITARYBASES:	militaryBaseDistanceGraph.draw(); break;
		case HOURS:	hoursGraph.draw(); break;
		case MONTHS: monthsGraph.draw(); break;
		case WEATHERSTATIONS: weatherStationsGraph.draw(); break;
		}
	}

	public boolean mouseOver()
	{
		if(!GV.hoursPanel.graphButton.state) return false;
		if(GV.processing.mouseX > x && GV.processing.mouseX < x + width && 
				GV.processing.mouseY > y && GV.processing.mouseY < y + height) 	return true;
		return false;
	}

	public void updateActiveGraph(){

		if(airport.state && activeGraph!=AIRPORT){
			createAirportGraphPoints();
			activeGraph=AIRPORT;
			popDensity.state=false;
			militaryBases.state=false;
			hours.state=false;
			months.state=false;
			weatherStations.state=false;
		}
		else if(popDensity.state && activeGraph!=POPDENSITY){
			createDensityGraphPoints();
			activeGraph=POPDENSITY;
			airport.state=false;
			militaryBases.state=false;
			hours.state=false;
			months.state=false;
			weatherStations.state=false;
		}
		else if(militaryBases.state && activeGraph!=MILITARYBASES){
			createMilitaryGraphPoints();
			activeGraph=MILITARYBASES;
			airport.state=false;
			popDensity.state=false;
			hours.state=false;
			months.state=false;
			weatherStations.state=false;
		}
		else if(hours.state && activeGraph!=HOURS){
			createHoursGraphPoints();
			activeGraph=HOURS;
			airport.state=false;
			popDensity.state=false;
			militaryBases.state=false;
			months.state=false;
			weatherStations.state=false;
		}
		else if(months.state && activeGraph!=MONTHS){
			createMonthGraphPoints();
			activeGraph=MONTHS;
			airport.state=false;
			popDensity.state=false;
			militaryBases.state=false;
			hours.state=false;
			weatherStations.state=false;
		}
		else if(weatherStations.state && activeGraph!=WEATHERSTATIONS){
			createWeatherStationsPoints();
			activeGraph=WEATHERSTATIONS;
			months.state=false;
			airport.state=false;
			popDensity.state=false;
			militaryBases.state=false;
			hours.state=false;
		}
	}


	public void createHoursGraphPoints(){		
		GV.graphPoints = new ArrayList<ArrayList<Integrator>>();

		int max=0;
		ArrayList<ArrayList<UFO>> a = new ArrayList<ArrayList<UFO>>();
		//init the ArrayList
		for(int i=0;i<24;i++){
			a.add(new ArrayList<UFO>());
			GV.graphPoints.add(new ArrayList<Integrator>());
		}
		//creates an ordered ArrayList from the ufo sights to display
		for(int i=0;i<GV.ufoToDisplay.size();i++){
			a.get(GV.ufoToDisplay.get(i).getDateOfSight().get(Calendar.HOUR_OF_DAY)).add(GV.ufoToDisplay.get(i));
		}
		
		int[] colorMapping = colorMapping();
		
		for(int i=0;i<24;i++){
			int val = function(a,colorMapping, i);
			if(max<val)max = val;
		} 			
		

		hoursGraph.maxYValue = max+(10-max%10);
		if(hoursGraph.maxYValue<10) hoursGraph.maxYValue=20;
	}
	public void createMonthGraphPoints(){		
		GV.graphPoints = new ArrayList<ArrayList<Integrator>>();

		int max=0;
		ArrayList<ArrayList<UFO>> a = new ArrayList<ArrayList<UFO>>();
		//init the ArrayList
		for(int i=0;i<12;i++){
			a.add(new ArrayList<UFO>());
			GV.graphPoints.add(new ArrayList<Integrator>());
		}
		//creates an ordered ArrayList from the ufo sights to display
		for(int i=0;i<GV.ufoToDisplay.size();i++){
			a.get(GV.ufoToDisplay.get(i).getDateOfSight().get(Calendar.MONTH)).add(GV.ufoToDisplay.get(i));
		}
		
		int[] colorMapping = colorMapping();
		
		for(int i=0;i<12;i++){
			int val = function(a,colorMapping, i);
			if(max<val)max = val;
		} 			
		
		monthsGraph.maxYValue = max+(10-max%10);
		if(monthsGraph.maxYValue<10) monthsGraph.maxYValue=20;


	}
	
	private int function(ArrayList<ArrayList<UFO>> a,int[] colorMapping,int i){
		int max =0;
		for(int j=0;j<GV.colors.length;j++){
			int[] count = new int[GV.colors.length];
			if(GV.shapeCategoryColor){
				for(int k =0;k<a.get(i).size();k++){
					if(GV.colors[0]==GV.shapeCol[a.get(i).get(k).getShape().shape.ordinal()])
					count[0]++;
					else if(GV.colors[1]==GV.shapeCol[a.get(i).get(k).getShape().shape.ordinal()])
						count[1]++;
					else if(GV.colors[2]==GV.shapeCol[a.get(i).get(k).getShape().shape.ordinal()])
						count[2]++;
					else if(GV.colors[3]==GV.shapeCol[a.get(i).get(k).getShape().shape.ordinal()])
						count[3]++;
				}
			}
			else{
				for(int k =0;k<a.get(i).size();k++){
					count[a.get(i).get(k).getShape().getCategory().ordinal()]++;
				}
			}
			for(int z=0;z<GV.colors.length;z++){
				Integrator val = new Integrator(0,i);
				val.target(count[z]);
				val.color = z;
				val.shapeNum = colorMapping[z];
				GV.graphPoints.get(i).add(val);
			}			
			if(max<a.get(i).size()) max = a.get(i).size();
		}
		return max;
	}
	
	private int[] colorMapping(){
		int[] colorMapping = new int[GV.colors.length];
		if(GV.shapeCategoryColor){
			for(int k =0;k<GV.shapesSelected.size();k++){
				if(GV.colors[0]==GV.shapeCol[GV.shapesSelected.get(k).getShapeIndex().ordinal()])
					colorMapping[0] = GV.shapesSelected.get(k).getShapeIndex().ordinal();
				else if(GV.colors[1]==GV.shapeCol[GV.shapesSelected.get(k).getShapeIndex().ordinal()])
					colorMapping[1] = GV.shapesSelected.get(k).getShapeIndex().ordinal();
				else if(GV.colors[2]==GV.shapeCol[GV.shapesSelected.get(k).getShapeIndex().ordinal()])
					colorMapping[2] = GV.shapesSelected.get(k).getShapeIndex().ordinal();
				else if(GV.colors[3]==GV.shapeCol[GV.shapesSelected.get(k).getShapeIndex().ordinal()])
					colorMapping[3] = GV.shapesSelected.get(k).getShapeIndex().ordinal();
			}
		}
		return colorMapping;
	}
	public void createAirportGraphPoints(){
		GV.graphPoints = new ArrayList<ArrayList<Integrator>>();

		int max=0;
		ArrayList<ArrayList<UFO>> a = new ArrayList<ArrayList<UFO>>();
		//init the ArrayList
		for(int i=0;i<createAirportXLabels().size();i++){
			a.add(new ArrayList<UFO>());
			GV.graphPoints.add(new ArrayList<Integrator>());
		}
		//creates an ordered ArrayList from the ufo sights to display
		for(int i=0;i<GV.ufoToDisplay.size();i++){
			//System.out.println(GV.ufoToDisplay.get(i).distanceFromClosestAirport);
			int value =(int) (GV.ufoToDisplay.get(i).distanceFromClosestAirport/10);
			if(value>a.size()-1){value=a.size()-1;}
			a.get(value).add(GV.ufoToDisplay.get(i));
		}
		
		int[] colorMapping = colorMapping();
		
		for(int i=0;i<createAirportXLabels().size();i++){
			int val = function(a,colorMapping, i);
			if(max<val)max = val;
		} 			 
		airportDistanceGraph.maxYValue = max+(10-max%10);
		if(airportDistanceGraph.maxYValue<10) airportDistanceGraph.maxYValue=20;
	}
	public void createMilitaryGraphPoints(){
		GV.graphPoints = new ArrayList<ArrayList<Integrator>>();

		int max=0;
		ArrayList<ArrayList<UFO>> a = new ArrayList<ArrayList<UFO>>();
		//init the ArrayList
		for(int i=0;i<createMilitaryXLabels().size();i++){
			a.add(new ArrayList<UFO>());
			GV.graphPoints.add(new ArrayList<Integrator>());
		}
		//creates an ordered ArrayList from the ufo sights to display
		for(int i=0;i<GV.ufoToDisplay.size();i++){
			//System.out.println(GV.ufoToDisplay.get(i).distanceFromClosestAirport);
			int value =(int) (GV.ufoToDisplay.get(i).distanceFromClosestMilitaryBase/10);
			if(value>a.size()-1){value=a.size()-1;}
			a.get(value).add(GV.ufoToDisplay.get(i));
		}
		
		int[] colorMapping = colorMapping();
		
		for(int i=0;i<createMilitaryXLabels().size();i++){
			int val = function(a,colorMapping, i);
			if(max<val)max = val;
		} 			
		
		militaryBaseDistanceGraph.maxYValue = max+(10-max%10);
		if(militaryBaseDistanceGraph.maxYValue<10) militaryBaseDistanceGraph.maxYValue=20;
	}
	public void createDensityGraphPoints(){
		GV.graphPoints = new ArrayList<ArrayList<Integrator>>();
		int max=0;
		ArrayList<ArrayList<UFO>> a = new ArrayList<ArrayList<UFO>>();
		//init the ArrayList
		for(int i=0;i<createPopDensityXLabels().size();i++){
			a.add(new ArrayList<UFO>());
			GV.graphPoints.add(new ArrayList<Integrator>());
		}
		//creates an ordered ArrayList from the ufo sights to display
		for(int i=0;i<GV.ufoToDisplay.size();i++){
			//System.out.println(GV.ufoToDisplay.get(i).distanceFromClosestAirport);
			int value =(int) (GV.ufoToDisplay.get(i).populationDensity/500);
			if(value>a.size()-1){value=a.size()-1;}
			a.get(value).add(GV.ufoToDisplay.get(i));
		}
		
		int[] colorMapping = colorMapping();
		
		for(int i=0;i<createPopDensityXLabels().size();i++){
			int val = function(a,colorMapping, i);
			if(max<val)max = val;
		} 			
		
		populationDensityGraph.maxYValue = max+(10-max%10);
		if(populationDensityGraph.maxYValue<10) populationDensityGraph.maxYValue=20;
		
	}
	public void createWeatherStationsPoints(){
		GV.graphPoints = new ArrayList<ArrayList<Integrator>>();
		
		int max=0;
		ArrayList<ArrayList<UFO>> a = new ArrayList<ArrayList<UFO>>();
		//init the ArrayList
		for(int i=0;i<createWeatherXLabels().size();i++){
			a.add(new ArrayList<UFO>());
			GV.graphPoints.add(new ArrayList<Integrator>());
		}
		//creates an ordered ArrayList from the ufo sights to display
		for(int i=0;i<GV.ufoToDisplay.size();i++){
			//System.out.println(GV.ufoToDisplay.get(i).distanceFromClosestAirport);
			int value =(int) (GV.ufoToDisplay.get(i).distanceFromClosestMilitaryBase/10);
			if(value>a.size()-1){value=a.size()-1;}
			a.get(value).add(GV.ufoToDisplay.get(i));
		}
		
		int[] colorMapping = colorMapping();
		
		for(int i=0;i<createWeatherXLabels().size();i++){
			int val = function(a,colorMapping, i);
			if(max<val)max = val;
		} 			
		
		weatherStationsGraph.maxYValue = max+(10-max%10);
		if(weatherStationsGraph.maxYValue<10) weatherStationsGraph.maxYValue=20;
		
		
	}
}
